// ==UserScript==
// @name           Translatorize-for-Identica
// @namespace      http://translatorize.com/
// @description    Translates user generated content in Identi.ca
// @author         Micah Wittman
// @include        http://*identi.ca/*
// @include        https://*identi.ca/*
// @version        0.12
// ==/UserScript==

/*************************************************************
    Copyright(c) 2009-2010 Micah Wittman
    
    Open Source License:
    Translatorize is licensed under the terms of the
        Open Source GPL 3.0 license.
        http://www.gnu.org/licenses/gpl.html
        
    Licensing inquiries: http://wittman.org/about/

    Translatorize                   http://translatorize.com 
    Translatorize - for Identi.ca   http://translatorize.com/for/identica/
    Source Code Project             http://code.google.com/p/translatorize/
    
	Author: Micah Wittman           http://wittman.org
                                    http://identi.ca/micah
                                    http://twitter.com/micahwittman
                                    http://friendfeed.com/micahwittman
                                    http://friendfeed.com/translatorize
                                    
	Versions:
		* 2010-01-08 - version 0.1.2 - jQuery now loaded by identi.ca. Translatorize call to load jQuery caused conflict. Removed redundant load.
		* 2009-09-26 - version 0.1.1 - Added newly supported languages by Google: Welsh and Yiddish.
		* 2009-08-22 - version 0.1.0 - Initial Release.
		
*************************************************************/

(function(){

	/*************************************************************
	******************** Configuration Begin *********************
	********************                     *********************/
	var scriptnameText = 'Translatorize';
	var translateLinkText = 'Translate X to URDU'; //The text of the translate link.
	var translateReverseLinkText = 'Translate URDU to X'; //The text of the reverse direction translate link.

	/*FOR ALL AVAILABLE GOOGLE TRANSLATION API SUPPORTED LANGUAGES SEE CODES
	HERE:
	http://code.google.com/apis/ajaxlanguage/documentation/reference.html#LangNameArray
	Codes as of 2009-09-26: 'AFRIKAANS' : 'af', 'ALBANIAN' : 'sq', 'AMHARIC' : 'am', 'ARABIC' : 'ar', 'ARMENIAN' : 'hy',
	'AZERBAIJANI' : 'az', 'BASQUE' : 'eu', 'BELARUSIAN' : 'be', 'BENGALI' : 'bn', 'BIHARI' : 'bh',
	'BULGARIAN' : 'bg', 'BURMESE' : 'my', 'CATALAN' : 'ca', 'CHEROKEE' : 'chr', 'CHINESE' : 'zh',
	'CHINESE_SIMPLIFIED' : 'zh-CN', 'CHINESE_TRADITIONAL' : 'zh-TW', 'CROATIAN' : 'hr', 'CZECH' : 'cs',
	'DANISH' : 'da', 'DHIVEHI' : 'dv', 'DUTCH': 'nl', 'ENGLISH' : 'en', 'ESPERANTO' : 'eo', 'ESTONIAN' :
	'et', 'FILIPINO' : 'tl', 'FINNISH' : 'fi', 'FRENCH' : 'fr', 'GALICIAN' : 'gl', 'GEORGIAN' : 'ka',
	'GERMAN' : 'de', 'GREEK' : 'el', 'GUARANI' : 'gn', 'GUJARATI' : 'gu', 'HEBREW' : 'iw', 'HINDI' :
	'hi', 'HUNGARIAN' : 'hu', 'ICELANDIC' : 'is', 'INDONESIAN' : 'id', 'INUKTITUT' : 'iu', 'IRISH' :
	'ga', 'ITALIAN' : 'it', 'JAPANESE' : 'ja', 'KANNADA' : 'kn', 'KAZAKH' : 'kk', 'KHMER' : 'km',
	'KOREAN' : 'ko', 'KURDISH': 'ku', 'KYRGYZ': 'ky', 'LAOTHIAN': 'lo', 'LATVIAN' : 'lv', 'LITHUANIAN' :
	'lt', 'MACEDONIAN' : 'mk', 'MALAY' : 'ms', 'MALAYALAM' : 'ml', 'MALTESE' : 'mt', 'MARATHI' : 'mr',
	'MONGOLIAN' : 'mn', 'NEPALI' : 'ne', 'NORWEGIAN' : 'no', 'ORIYA' : 'or', 'PASHTO' : 'ps', 'PERSIAN'
	: 'fa', 'POLISH' : 'pl', 'PORTUGUESE' : 'pt-PT', 'PUNJABI' : 'pa', 'ROMANIAN' : 'ro', 'RUSSIAN' :
	'ru', 'SANSKRIT' : 'sa', 'SERBIAN' : 'sr', 'SINDHI' : 'sd', 'SINHALESE' : 'si', 'SLOVAK' : 'sk',
	'SLOVENIAN' : 'sl', 'SPANISH' : 'es', 'SWAHILI' : 'sw', 'SWEDISH' : 'sv', 'TAJIK' : 'tg', 'TAMIL' :
	'ta', 'TAGALOG' : 'tl', 'TELUGU' : 'te', 'THAI' : 'th', 'TIBETAN' : 'bo', 'TURKISH' : 'tr',
	'UKRAINIAN' : 'uk', 'URDU' : 'ur', 'UZBEK' : 'uz', 'UIGHUR' : 'ug', 'VIETNAMESE' : 'vi', 'WELSH' :
	'cy', 'YIDDISH' : 'yi', 'UNKNOWN' : ''*/

	var languageCodeFrom = ''; // Translated FROM - (Empty string '' activates auto-detect, which is the default). Language code as defined by google's translation api - original text. (e.g. '' = auto-detect, 'fa' = Farsi, etc.)
	var languageCodeTo = 'ur'; //Translated TO - Language code as defined by google's translation api - translated text (e.g. 'en' = English)

	var translationBackgroundColorFrom = 'rgb(240,240,240)'; //background color of original text (e.g. gray)
	var translationBackgroundColorTo = 'rgb(255,245,175)'; //background color of translated text (e.g. wheat)

	var autoTranslateEnabled = true; //Set to true to automatically translate title/comments when a single entry page is loaded.
	var autoTranslateRealtimeEnabled = true; //Set to true to automatically translate title/comments when a single entry page is loaded.
	var keepOriginalTextInRealtime = true; //Set to true to show the translated text and the original text in a realtime stream. By default it is only shown in single post view.

	var translateTitleOnlyInRealtime = false; //Set to true to only translate an entry title (not comments) in a feed stream.

	var autoProtocolMatchingEnabled = true; //Set to true to automatically set all URL references to secure protocol (https) if the current page is https.

	var onlyUseSecureProtocolCompatibleFeatures = true; //Set to true to only use features in script that can utilize a secure connection - https (only applies when the page is using an https connection). Note: currently, this only affects one aspect of this script: that userscripts.org does not support https, so the auto-script update feature will disabled if this is set to true.

	var translateDelay = 2000; //Number of milliseconds by which the realtime feed update is delayed (integer). Set to -1 (negative 1) for an indefinite delay.

	/******************** Configuration End ***********************
	***************************************************************/


	/******************** Pre-Setup Global Variables ************************/
	var protocol = 'http://';
	
	
	/******************** Pre-Setup Functions *******************************/

	function setProtocol()
	{
		if(autoProtocolMatchingEnabled)
		{
			protocol = window.location.protocol + '//';
		}
		if(protocol == 'http://')
		{
			onlyUseSecureProtocolCompatibleFeatures = false; //not a secure connection, so use all features
		}
	}
	setProtocol();


	/******************** Global Variables ************************/
	var version = 'v0.1';
	var prevEntryAndCommentCount = null;
	var entries;
	var comments;
	var url = window.location.href;
	var urlPrev = window.location.href;
	var transParagraphCount = 0;
	var linkContent = '<a id="translateLink" href="#" style="color:white;background-color:rgb(80,80,80);padding:0;font-weight:bold">' + translateLinkText + '</a>';
	var linkDivStyleFlyout = 'z-index:2;cursor:auto; position:absolute; height:255px; min-height:250; background-color:rgb(80,80,80); border-color:darkgray; '
		+ 'color:white; font-weight:normal; padding:4px; display:block;width:195px';
	var linkDivStyle = 'z-index:2;cursor:pointer;margin:4px 0 0 13px; color:white;background-color:rgb(80,80,80);font-weight:normal;padding:0 0 3px 3px; '
		+'display:block; width:195px;overflow:hidden;height:1.5em; -moz-border-radius:5px';
	var linkDiv = 
			' <div id="translateLinkDiv" style="' + linkDivStyle + '">' 
				+ '<div id="identicaTranslateScriptname" style="padding: 0 0 6px 3px;border-color:solid 1px gray;">'
					+ scriptnameText + ' Panel ' + ' (<span style="color:white" id="translatorizeTransParagraphCount">' + transParagraphCount + '</span>)'
				+ '</div>'
				+ '<div style="padding:4px 0 0 4px;">'
					+ linkContent
				+ '</div>'
				+ '<br /><br />'
				+ '<table style="border-style:none">'
					+'<tr>'
						+'<td>'
							+'<div>'
								+'<a href="' + protocol + 'translatorize.com/" title="Translatorize"><img style="color:white;vertical-align:middle" id="translatorizePanel" src="' + protocol + 'translatorize.googlecode.com/files/translatorize-panel-id.png" alt="Translatorize"/></a>'
							+'</div>'
						+'</td>' 
						+ '<td>'
							+ '<span style="margin:0 0 0 4px;font-size:11px;color:rgb(240,240,240);">' + version + '</span>'
						+ '</td>'
					+'</tr>'
				+'</table>'
				+ '<div id="identicaTranslateDonateDiv" height="149" width="100%" style="margin:6px 0 20px 0; padding:4px 0 0 0;">'
				+ '</div>'
			+ '</div>';
		
		
		
		
	var linkReverseDiv = '<div id="translateReverse" style="padding:4px 0 0 0;"><a id="translateReverseLink" style="color:white;font-weight:bold" href="#"><span>'
		+ translateReverseLinkText + '&nbsp;</span></a></div>';
	var languageCodeFromToUse;
	var languageCodeToToUse;
	var isOneEntry;
	var doAutoTranslate;
	var identicaTranslateSource = 'identicaTranslateSource';


	/****************** Initializing Functions ********************/
	function GM_wait()
	{
	    if(typeof unsafeWindow != 'undefined')
	    {
	        if(typeof unsafeWindow.jQuery != 'undefined')
	        {
				jQuery = unsafeWindow.jQuery;
	        }
	    }
	    if(typeof jQuery == 'undefined')
	    {
			window.setTimeout(GM_wait,251);
	    }
	    else
	    {
			letsJQuery();
	    }
	}

	function letsJQuery()
	{
		setIsOneEntry();
		setDoStartAutoTranslate();

		TranslateLink();
		
		if(doAutoTranslate)
		{
			window.setTimeout(autoTranslate, 2000);
		}
	}



	/************************ Helper Functions ********************/
	function setEntries()
	{
		entries = jQuery('#content p.entry-content');
	}
	
	function setComments()
	{
		//not applicable to identica
	}

	function setidenticaTranslateSource()
	{
		identicaTranslateSource = 'identicaTranslateSource';
	}
	
	function setidenticaTranslateSourceReverse()
	{
		identicaTranslateSource = 'identicaTranslateSourceReverse';
	}
	
	function google_wait()
	{
	    if(typeof unsafeWindow != 'undefined')
	    {
	        if(typeof unsafeWindow.google != 'undefined')
	        {
				google = unsafeWindow.google;
	        }
	    }
	    if(typeof google == 'undefined')
	    {
			window.setTimeout(google_wait,50);
	    }
	    else
	    {
			googleApiLoad();
	    }
	}

	function requestGoogleScript()
	{
		//Request Script
		var head = document.getElementsByTagName("head")[0];
		var script = document.createElement("script");
	    script.setAttribute("language", "javascript");
	    script.setAttribute("src", protocol + 'www.google.com/jsapi');
	    head.appendChild(script);
	}

	function setTranslationDirectionDefault()
	{
		setidenticaTranslateSource();
		languageCodeFromToUse = languageCodeFrom;
		languageCodeToToUse = languageCodeTo;
	}

	function setTranslationDirectionReverse()
	{
		setidenticaTranslateSourceReverse();
		languageCodeFromToUse = languageCodeTo;
		languageCodeToToUse = languageCodeFrom;
	}

	function googleLoadControllerDefault()
	{
		setTranslationDirectionDefault();
		googleLoadController();
		return false;
	}

	function googleLoadControllerReverse()
	{
		setTranslationDirectionReverse();
		googleLoadController();
	}

	function googleLoadController()
	{

	    if(typeof unsafeWindow != 'undefined')
	    {
	        if(typeof unsafeWindow.google != 'undefined')
	        {
				google = unsafeWindow.google;
	        }
	    }
	    if(typeof google == 'undefined')
	    {
			requestGoogleScript();
			google_wait();
		}
		else
		{
			googleApiLoad();
		}
	}

	function googleApiLoad(){
		google.load('language','1',{"callback":googleApiLoadCallback});
	}

	function googleApiLoadCallback()
	{
		setEntries();
		setComments();
		TranslateProcess();
		Translate_wait();
	}

	function translatedLabelText()
	{
		if(languageCodeFromToUse == languageCodeTo)
		{
			return 'Translated ' + translateReverseLinkText.replace('Translate ',' ') + ' ';
		}
		else
		{
			return  'Translated ' + translateLinkText.replace('Translate ',' ');
		}
	}

	function autoTranslate()
	{
		jQuery('#translateLink').trigger('click');
	}

	function doTranslation(result)
	{
		var doTran = false;
		if(languageCodeFromToUse != '')
		{
			doTran = true;
		}
		else
		{
			if(typeof result != 'undefined')
			{
				if(typeof result.detectedSourceLanguage != 'undefined')
				{
					if(result.detectedSourceLanguage != languageCodeTo)
					{
						doTran = true;
					}
				}
			}
		}
		return doTran;
	}
	
	function Translate_wait()
	{
		setEntries();
		//setComments(); //not applicable to identica
		var entryAndCommentCount = entries.length + jQuery('.identicaTranslate').length;
	    var translateDelayToUse = translateDelay;

	    if(translateDelay < 0)
	    {
	        translateDelayToUse = 2000;
	    }
		if(entryAndCommentCount == prevEntryAndCommentCount)
		{
			window.setTimeout(Translate_wait, translateDelayToUse);
		}
		else
		{
			prevEntryAndCommentCount = entryAndCommentCount;
			if(translateDelay >= 0)
			{
				TranslateProcess();
				Translate_wait();
			}
		}
	}
	
	function setIsOneEntry()
	{
		return true; //not applicable in fb
	}

	function setDoStartAutoTranslate()
	{
		doAutoTranslate = doStartAutoTranslate();
	}

	function doStartAutoTranslate()
	{
		var doStartAutoTrans = false;
		if(isOneEntry)
		{
			//One Entry
			if(autoTranslateEnabled)
			{
				doStartAutoTrans = true;
			}
		}
		else
		{
			//Stream
			if(autoTranslateRealtimeEnabled)
			{
				doStartAutoTrans = true;
			}
		}
		return doStartAutoTrans;
	}

	function titleIsOnlyUsername(title)
	{
		return false; //not applicable to identica
	}

	function preTranslateHtmlScrub(html)
	{
		return html.replace(/<img[^>]+>/g,' ');
	}



	/***************** Main Processing Functions ******************/
	function TranslateLink()
	{ 
		if(jQuery('#translateLink, translateLinkDiv').length == 0)
		{
			var donateLinkHtml = '<a href="' + protocol + 'pledgie.com/campaigns/5387"><img height="37" width="149" alt="Click here to lend your support to: Translatorize and make a donation at www.pledgie.com !" src="' + protocol + 'pledgie.com/campaigns/5387.png?skin_name=chrome" border="0" /></a>';
			var panel = jQuery('#site_notice'); //#side .section-header
			if(panel.length > 0)
			{
				//panel.append('<div>TEST 123'+Math.floor(Math.random()*101)+'</div>');
				panel.append(''+linkDiv+'');
			}
			else
			{
				//panel = jQuery('#content');
				//panel.prepend(linkDiv);
			}

			jQuery('#translateLink').click(googleLoadControllerDefault);
			jQuery('#translateLinkDiv')
				.hover(function(){
					if(jQuery(this).css('opacity') == '1')
					{
						var identicaTranslateDonateDiv = jQuery('#identicaTranslateDonateDiv');
						if(identicaTranslateDonateDiv.children().length == 0)
						{
							identicaTranslateDonateDiv.append(donateLinkHtml);
						}
						jQuery(this).hide().fadeIn(50, function(){
							jQuery(this).attr('style', linkDivStyleFlyout); //On hover over
						});
					}
	         	}, function(){  //On hover out  
					jQuery(this).fadeOut(300, function(){
						jQuery(this).attr('style', linkDivStyle);
						jQuery(this).removeClass('tranlatorizePanelMax');
					})
					.show()
					.click(function(){
						if(!jQuery(this).hasClass('tranlatorizePanelMax'))
						{
							jQuery(this).addClass('tranlatorizePanelMax');
							var identicaTranslateDonateDiv = jQuery('#identicaTranslateDonateDiv');
							if(identicaTranslateDonateDiv.children().length == 0)
							{
								identicaTranslateDonateDiv.append(donateLinkHtml);
							}
							jQuery(this).hide().fadeIn(50, function(){
								jQuery(this).attr('style', linkDivStyleFlyout); //On hover over
							});
						}
				});
			});
		}
	}

	function TranslateProcess()
	{
		var afterClickLinkContent = '<div id="translateAfter" style="padding:2px 0 2px 0;color:rgb(255,225,10);font-weight:bold">&nbsp;' + '&gt;&gt; Processed &lt;&lt;' + '&nbsp; <span id="translateUndo"><a style="color:white;font-size:10px" href="#" onclick="window.location.reload(false); return false;">Undo</a></span></div>';
		var titles = entries;
		var titleOnlyUsername = false;
		var titleHtml;
		var insertHtml;
		var shouldTranslate = true;
	
		titles.each(function(){
		
			var title = jQuery(this);  
			var titleOnlyUsername = titleIsOnlyUsername(title);
			if(!title.hasClass(identicaTranslateSource) && !titleOnlyUsername && title.css('display') != 'none')
			{
				if(title.css('display') != 'none')
				{
					title.addClass(identicaTranslateSource);
				}
				titleHtml = preTranslateHtmlScrub(title.html()); 
				google.language.translate(titleHtml, languageCodeFromToUse, languageCodeToToUse, function(result){
					if(doTranslation(result))
					{
						if(result.translation) {
							insertHtml = '<div class="identicaTranslate" style="margin:4px 0 4px 4em;padding:2px 4px 2px 4px;background-color:' + translationBackgroundColorTo + '">' + result.translation + '</div>';
						
							shouldTranslate = true;
							if(title.hasClass('label') && title[0].tagName == 'TD')
							{
								shouldTranslate = false;
							}
						
							if(shouldTranslate)
							{
								transParagraphCount++;
								jQuery('#translatorizeTransParagraphCount').empty().append(transParagraphCount);
								if(title[0].tagName == 'DD' || title[0].tagName == 'TD')
								{
									title.append(insertHtml); //is an info tab <dd>, so append, not insert after.
								}
								else
								{
									title.after(insertHtml);
								}
								if(!isOneEntry && !keepOriginalTextInRealtime)
								{
									title.hide();
								}
							}
						}
					}
				
				});
			}
		});
	
		//Translate comments [[not applicable to identica]]

		//After translations inserts
		jQuery('#translateAfter').remove();
		jQuery('#translateUndo').remove();

		jQuery('#identicaTranslateScriptname').after(afterClickLinkContent);
	
		jQuery('#translateReverse').remove();
		if(languageCodeFrom != '')
		{
			jQuery('#translateLink').after(linkReverseDiv);		
			jQuery('#translateReverseLink').click(googleLoadControllerReverse);
		}
		return false;
	}


	/*************************************************************
	************************** RUN SCRIPT ************************
	********************                     *********************/
	if(window.location.href.indexOf('identi.ca/') > -1) //greasekit doesn't support @include directs, so test URL for context
	{
		GM_wait();
	}

})();